57. 绘制散点图

本章概要

  • 学习材料:风险收益、规模与超额收益教学示例。
  • 本章任务:运行 fig-bubble-chart-outputfig-capm-scatter-output,绘制气泡图并估计证券特征线。
  • 完成后你将得到:气泡面积映射、alpha/beta/残差标准差和带依据标识图形。
  • 自我检查:检查气泡面积单调、残差均值近零;不得把beta写成总风险或alpha写成稳定跑赢。
  • 拓展练习:把CAPM方法应用到另一中性超额收益序列。

散点图:揭示两个变量之间的关系

散点图(Scatter Plot)是展示两个变量关系最直观的工具

在商业与金融分析中,散点图帮助我们:

  • 识别相关性:正相关、负相关、无相关
  • 发现模式:线性、非线性、聚类
  • 检测异常值:远离主群体的数据点
  • 验证假设:风险与收益、规模与回报的关系

散点图的数学基础:相关系数

散点图展示两个变量 \((X, Y)\) 的关系:

\[ \large \{(x_1, y_1), (x_2, y_2), \ldots, (x_n, y_n)\} \]

Pearson 相关系数衡量线性相关程度:

\[ \large \rho_{XY} = \frac{\sum(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum(x_i - \bar{x})^2}\sqrt{\sum(y_i - \bar{y})^2}} \]

相关系数的视觉特征

相关系数 散点图特征 含义
\(\rho \approx 1\) 点从左下到右上,直线上升 强正相关
\(\rho \approx -1\) 点从左上到右下,直线下降 强负相关
\(\rho \approx 0\) 点散乱,无明显方向 无线性相关

运行前预测|平台任务解答代码

  • 输入预测:运行前先写出 index_closepriceindex_return 的业务含义、数据类型或取值范围,并判断哪一个输入最可能改变结果。
  • 结果预测:不展开答案,先预测将得到index_return 的结果;同时写出方向、数量级或表格/图形结构。
  • 完成要求:能独立说明本任务从输入到“平台任务解答代码”结果的关键步骤,原样录入平台代码并得到可核对的运行结果。

⭐ 平台任务解答代码

展开完整代码(投影默认折叠)
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
#任务一
import pandas as pd
index_closeprice = pd.read_excel("https://huoran.oss-cn-shenzhen.aliyuncs.com/1726722771060.xlsx") #导入数据
index_closeprice["日期"] = pd.to_datetime(index_closeprice["日期"] , format='%Y%m%d')  # 转换为日期时间格式
index_closeprice.set_index("日期",inplace=True)  # 将日期列设为index_closeprice数据框的索引
index_return = index_closeprice/index_closeprice.shift(1)-1 #计算股指的周涨跌幅 
index_return = index_return.dropna() #删除缺失值
print(index_return.corr())  #计算指数周涨跌幅的相关系数


#任务二
import matplotlib.pyplot as plt
import pandas as pd  # 导入Pandas数据分析库
plt.rcParams['font.sans-serif']=['SimHei']   # 用黑体显示中文
plt.rcParams['axes.unicode_minus']=False     # 正常显示负号


index_closeprice = pd.read_excel("https://huoran.oss-cn-shenzhen.aliyuncs.com/1726722771060.xlsx") #导入数据
index_closeprice["日期"] = pd.to_datetime(index_closeprice["日期"] , format='%Y%m%d')  # 转换为日期时间格式
index_closeprice.set_index("日期",inplace=True)  # 将日期列设为index_closeprice数据框的索引
index_return = index_closeprice/index_closeprice.shift(1)-1 #计算股指的周涨跌幅
index_return = index_return.dropna() #删除缺失值
plt.figure(figsize=(11,6))  # 创建图形画布
plt.subplot(1,2,1)  #第1行、第1列子图
plt.scatter(x=index_return.iloc[:,-1],y=index_return.iloc[:,0],c="c",marker="o")    #创业板指与上证综指的散点图 
plt.xlabel(u"创业板指",fontsize=13)  # 设置X轴标签
plt.ylabel(u"上证综指",fontsize=13,rotation=90)  # 设置Y轴标签
plt.xticks(fontsize=13)  # 设置X轴刻度标签
plt.yticks(fontsize=13)  # 设置Y轴刻度标签
plt.title(u"创业板指与上证综指的散点图",fontsize=15)  # 设置图表标题
plt.grid(True)  # 显示网格线
plt.subplot(1,2,2,sharex=plt.subplot(1,2,1),sharey=plt.subplot(1,2,1))  #与第一个子图共用X轴和Y轴
plt.scatter(x=index_return.iloc[:,-1],y=index_return.iloc[:,1],c="c",marker="o")  # 绘制散点图
plt.xlabel(u"创业板指",fontsize=13)  # 设置X轴标签
plt.ylabel(u"深证成指",fontsize=13,rotation=90)  # 设置Y轴标签
plt.xticks(fontsize=13)  # 设置X轴刻度标签
plt.yticks(fontsize=13)  # 设置Y轴刻度标签
plt.title(u"创业板指与深证成指的散点图",fontsize=15)  # 设置图表标题
plt.grid(True)  # 显示网格线
plt.savefig("1.png")  # 保存图形至文件

任务复盘|平台任务解答代码

运行后核对:核对 index_closepriceindex_return 是否按预测参与运算,实际输出是否与预测一致;若不一致,先检查类型、单位、索引/字段和运算顺序。

拓展练习:把数据替换为一个中国企业或市场序列,改变一个分组或时间窗口;说明图形结论是否改变,以及为何。

基础散点图:风险与收益的关系

展开完整代码
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

# 创建风险-收益数据
np.random.seed(42)
n_stocks = 50

# 构造预设正关系的教学示例,不将结果解释为市场规律
risk = np.random.uniform(0.1, 0.4, n_stocks)
return_mean = 0.03 + 0.5 * risk + np.random.normal(0, 0.02, n_stocks)

# 绘制散点图
plt.figure(figsize=(10, 4.2))
plt.scatter(risk, return_mean, s=100, alpha=0.7, color='#2E86AB', edgecolors='white')

# 添加拟合线
z = np.polyfit(risk, return_mean, 1)
p = np.poly1d(z)
plt.plot(risk, p(risk), 'r--', linewidth=2, label=f'教学示例,非市场观测|拟合线: y={z[0]:.2f}x+{z[1]:.3f}')  # 在图例保留依据边界

plt.xlabel('风险(标准差)', fontsize=16)
plt.ylabel('期望收益率', fontsize=16)
plt.title('教学示例,非市场观测|风险收益点云', fontsize=16, fontweight='bold')  # 在可见标题声明依据边界
plt.legend(fontsize=16, title='教学示例,非市场观测')  # 在基础散点图例标题持续声明依据边界
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
教学示例,非市场观测。随机点云仅演示散点、拟合线与相关系数的计算。
Figure 1: 教学示例,非市场观测|预设风险收益点云

基础散点图:结果核对

展开相关系数核对代码
correlation = np.corrcoef(risk, return_mean)[0, 1]
print(f'教学示例,非市场观测|风险与收益的相关系数: {correlation:.4f}')  # 在孤立输出保留依据边界
教学示例,非市场观测|风险与收益的相关系数: 0.9167

scatter 关键参数详解

参数 说明 示例
s 点大小(面积) s=100 适合大多数场景
alpha 透明度,重叠点仍可见 alpha=0.7
color 点颜色 color='#2E86AB'
edgecolors 点边缘颜色 edgecolors='white' 更清晰
marker 点形状 marker='o' 圆形
linewidths 边缘线宽 linewidths=1.5

多组散点图:中性类别对比

以下随机数固定种子,仅用于演示分组图形语法;类别 A/B/C 不对应企业、行业或投资结论。

展开完整参考实现
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

# 创建三个中性类别的教学示例
np.random.seed(42)
industries = {
    '类别A': {'risk': np.random.uniform(0.1, 0.2, 15),  # 生成类别A横轴示例数据
             'return': np.random.normal(0.04, 0.01, 15)},
    '类别B': {'risk': np.random.uniform(0.25, 0.45, 15),  # 生成类别B横轴示例数据
             'return': np.random.normal(0.08, 0.02, 15)},
    '类别C': {'risk': np.random.uniform(0.08, 0.15, 15),  # 生成类别C横轴示例数据
                 'return': np.random.normal(0.03, 0.008, 15)}
}

colors = {'类别A': '#E3120B', '类别B': '#008080', '类别C': '#F0A700'}

plt.figure(figsize=(9.5, 4.0))  # 使用更宽画布分离点云、色标与标注
for industry, data in industries.items():
    plt.scatter(data['risk'], data['return'],
                s=120, alpha=0.7, color=colors[industry],
                edgecolors='white', label=industry, linewidths=1.5)

plt.xlabel('风险(标准差)', fontsize=16)
plt.ylabel('收益率', fontsize=16)
plt.title('教学示例,非市场观测|中性类别点云', fontsize=16, fontweight='bold')  # 标明点云不对应真实行业
plt.legend(fontsize=16, loc='upper left', title='教学示例,非市场观测')  # 在类别图例标题持续声明依据边界
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
教学示例,非市场观测。类别A、B、C三组中性点云仅演示分组颜色、图例和重叠。
Figure 2: 教学示例,非市场观测|中性类别点云输出

多组散点图的可视化策略

绘制多组数据时,需注意以下要点:

  • 颜色区分:每个类别用不同颜色,确保色差明显
  • 图例清晰:标注每个颜色对应的含义
  • 点大小一致:便于比较各组的密度分布
  • 边缘线:白色边缘使重叠点更清晰
  • 透明度alpha=0.7 让重叠区域可辨识

气泡图:三维数据展示

展开完整参考实现
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

# 创建三维数据(风险、收益、市值)
np.random.seed(42)
n = 30
data = pd.DataFrame({
    '风险': np.random.uniform(0.1, 0.4, n),
    '收益': np.random.normal(0.05, 0.02, n),
    '市值': np.random.uniform(50, 500, n)
})

plt.figure(figsize=(8, 3.2))  # 使用投影安全画布为教学示例声明和页脚保留空间
scatter = plt.scatter(data['风险'], data['收益'],
                      s=data['市值'] / 2, c=data['市值'],
                      cmap='Blues', alpha=0.6,
                      edgecolors='white', linewidths=1.5)  # 用面积与颜色双重映射第三变量

cbar = plt.colorbar(scatter)
cbar.set_label('预设第三变量(非市场观测)', fontsize=14)  # 用精简色标保留依据边界

# 标注市值最大的3家公司
top3 = data.nlargest(3, '市值')
for idx, row in top3.iterrows():
    plt.annotate(f'市值{row["市值"]:.0f}亿',
                 (row['风险'], row['收益']),
                 xytext=(5, -16), textcoords='offset points',
                 fontsize=12, bbox=dict(boxstyle='round,pad=0.3',
                                       facecolor='yellow', alpha=0.3))

plt.xlabel('风险(标准差)', fontsize=16)
plt.ylabel('收益率', fontsize=16)
plt.title('教学示例,非市场观测|三变量气泡图', fontsize=16, fontweight='bold')  # 在可见标题声明依据边界
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
教学示例,非市场观测。随机点云用横纵坐标、气泡面积和颜色演示三个变量。
Figure 3: 教学示例,非市场观测|三变量气泡图输出

气泡图的设计要点

  • 第三维度:气泡大小表示第三个变量(如市值)
  • 大小比例:避免气泡过大遮挡,过小看不见
  • 颜色映射:可用颜色强化第三维信息(双重编码)
  • 标注关键点:只标注重要数据点,避免文字拥挤
  • 颜色条:添加 colorbar 说明颜色与数值的映射

散点图矩阵:多变量关系探索

展开完整代码
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from pandas.plotting import scatter_matrix

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

np.random.seed(42)
df_multi = pd.DataFrame({
    'PE': np.random.uniform(10, 60, 100),
    'ROE': np.random.uniform(0.05, 0.35, 100),
    '收益率': np.random.normal(0.05, 0.02, 100)
})

axes = scatter_matrix(df_multi, alpha=0.6, diagonal='kde',
                      c='#2E86AB', edgecolors='white',
                      figsize=(6.5, 3.8))

for axis_row in axes:
    for axis in axis_row:
        axis.tick_params(labelsize=16)
        axis.xaxis.label.set_size(16)
        axis.yaxis.label.set_size(16)

plt.suptitle('教学示例,非市场观测|三变量散点矩阵', fontsize=18, fontweight='bold', y=1.01)  # 在可见标题声明依据边界
plt.tight_layout()
plt.show()
教学示例,非市场观测。随机三变量的对角核密度与两两散点仅演示矩阵语法。
Figure 4: 教学示例,非市场观测|三变量散点图矩阵

散点图矩阵:相关系数核对

展开相关系数核对代码
print('教学示例,非市场观测|相关系数矩阵:')  # 在孤立输出表头保留依据边界
print(df_multi.corr().round(3).to_string())
教学示例,非市场观测|相关系数矩阵:
        PE    ROE    收益率
PE   1.000 -0.034 -0.108
ROE -0.034  1.000  0.213
收益率 -0.108  0.213  1.000

散点图矩阵的应用场景

散点图矩阵可快速探索多个变量两两之间的关系:

  • 探索性数据分析(EDA):快速发现变量间的关系模式
  • 特征选择:识别高度相关的特征,避免多重共线性
  • 对角线diagonal='kde' 显示各变量的核密度估计
  • 多元正态性检验:判断联合分布是否近似正态

回归线与置信区间

展开完整代码
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

# 创建数据
np.random.seed(42)
x = np.random.uniform(0, 10, 100)
y = 2 + 1.5 * x + np.random.normal(0, 2, 100)

# 绘制带回归线的散点图
plt.figure(figsize=(10, 4.2))
sns.regplot(x=x, y=y,
            scatter_kws={'s': 80, 'alpha': 0.6, 'color': '#2E86AB'},
            line_kws={'color': '#E3120B', 'linewidth': 2.5},
            ci=95)

plt.xlabel('X变量', fontsize=16)
plt.ylabel('Y变量', fontsize=16)
plt.title('教学示例,非市场观测|回归线与置信带', fontsize=16, fontweight='bold')  # 在可见标题声明依据边界
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
教学示例,非市场观测。预设线性关系的随机点、拟合线和95%置信带。
Figure 5: 教学示例,非市场观测|回归线与置信带

回归线与置信区间:结果核对

展开回归统计核对代码
# 计算回归统计
from scipy import stats
slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
print(f'教学示例,非市场观测|回归方程: y = {slope:.2f}x + {intercept:.2f}')  # 在孤立输出表头保留依据边界
print(f'R² = {r_value**2:.4f}')
print(f'p值 = {p_value:.4e}')
教学示例,非市场观测|回归方程: y = 1.41x + 2.43
R² = 0.8434
p值 = 3.1046e-41

置信区间的含义

  • 95%置信区间:若按同一机制重复抽样并以同一方法构造区间,长期约有 95% 的区间覆盖真实回归均值;不能解释为本次真实线有 95% 概率落入阴影
  • 形状特征:两端较宽(数据少时不确定性大),中间较窄
  • sns.regplot:Seaborn 自动计算并绘制置信区间
  • ci=95:设置置信水平,常用 90%、95%、99%

金融应用:CAPM 模型可视化

展开完整参考实现
import matplotlib.pyplot as plt
import numpy as np

plt.rcParams['font.sans-serif'] = ['Source Han Serif SC']
plt.rcParams['axes.unicode_minus'] = False

# 构造中性资产的超额收益纯教学示例,不代表真实证券
np.random.seed(42)
n_obs = 60
market_return = np.random.normal(0.0008, 0.015, n_obs)
risk_free_return = 0.0001  # 设置教学示例的同期无风险收益
market_excess = market_return - risk_free_return  # 计算市场超额收益
beta = 1.2
alpha = 0.0002
stock_excess = alpha + beta * market_excess + np.random.normal(0, 0.01, n_obs)  # 生成中性资产超额收益

# 绘制证券特征线
plt.figure(figsize=(8, 3.2))  # 使用投影安全画布为CAPM方法边界图注和页脚保留空间
plt.scatter(market_excess, stock_excess,  # 绘制超额收益时间序列散点
            s=80, alpha=0.6, color='#2E86AB', edgecolors='white')

# 添加拟合线
z = np.polyfit(market_excess, stock_excess, 1)  # 拟合证券特征线斜率与截距
p = np.poly1d(z)
x_line = np.linspace(market_excess.min(), market_excess.max(), 100)  # 生成特征线横轴网格
plt.plot(x_line, p(x_line), 'r-', linewidth=2.5, label='证券特征线(时间序列)')  # 绘制拟合证券特征线

# 添加理论线(alpha=0)
plt.plot(x_line, beta * x_line, 'g--', linewidth=2, alpha=0.7, label='理论线(α=0)')  # 绘制零截距对照线

plt.xlabel('市场超额收益率 $R_m-R_f$', fontsize=16)  # 标注市场超额收益横轴
plt.ylabel('资产超额收益率 $R_i-R_f$', fontsize=16)  # 标注资产超额收益纵轴
plt.title(f'教学示例,非市场观测|CAPM: β={beta:.2f}, α={alpha:.4f}', fontsize=16, fontweight='bold')  # 在可见标题声明依据边界
plt.legend(fontsize=14, title='教学示例,非市场观测', loc='upper left')  # 用紧凑图例减少对点云遮挡
plt.grid(True, alpha=0.3)
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.5)
plt.axvline(x=0, color='k', linestyle='-', linewidth=0.5)
plt.tight_layout()
plt.show()
教学示例,非市场观测。市场与资产超额收益点云、拟合证券特征线及零截距理论线。
Figure 6: 教学示例,非市场观测|CAPM超额收益输出

CAPM 模型:拟合结果核对

展开 CAPM 拟合统计代码
# 统计量
correlation = np.corrcoef(market_excess, stock_excess)[0, 1]  # 核对两条超额收益序列相关系数
r_squared = correlation ** 2
print('教学示例,非市场观测|CAPM拟合统计')  # 在孤立输出表头保留依据边界
print(f'Beta (β): {z[0]:.2f}')
print(f'Alpha (α): {z[1]:.4f}')
print(f'R²: {r_squared:.4f}')
教学示例,非市场观测|CAPM拟合统计
Beta (β): 1.25
Alpha (α): 0.0002
R²: 0.7667

CAPM 模型核心概念

时间序列证券特征线\(R_i-R_f = \alpha + \beta(R_m-R_f)+\epsilon\)。本图在时间维度回归单一资产超额收益,称“证券特征线”;证券市场线(SML)是在横截面上比较期望收益与 beta,两者不可混称。

参数 含义 解读
\(\beta > 1\) 市场敏感度较高 市场超额收益变动 1 单位时,模型条件均值变动超过 1 单位
\(0<\beta<1\) 市场敏感度较低 系统性风险暴露较低;含特质残差的总波动仍可能更大
\(\beta = 1\) 单位市场敏感度 只约束系统性部分,不等于价格路径完全同步
\(\alpha > 0\) 正模型截距 在给定模型、期间与频率下的异常收益估计,不自动等于稳定跑赢

核对边界:总方差还包含残差方差,\(\operatorname{Var}(R_i-R_f)=\beta^2\operatorname{Var}(R_m-R_f)+\operatorname{Var}(\epsilon)\)(在残差与市场超额收益正交的模型假设下);因此不能只凭 beta 判断总波动。

本章小结

图表类型 适用场景 核心函数
基础散点图 两变量关系 plt.scatter()
多组散点图 分类对比 循环 + label
气泡图 三维数据展示 s= 控制大小
散点图矩阵 多变量探索 scatter_matrix()
回归散点图 线性关系验证 sns.regplot()
CAPM 特征线 金融建模 拟合 + 理论线

随堂练习

  • 问题 1|需要准备哪些数据?:风险收益、规模与超额收益教学示例。
  • 问题 2|需要完成哪些操作?:运行 fig-bubble-chart-outputfig-capm-scatter-output,绘制气泡图并估计证券特征线。
  • 问题 3|应得到哪些结果?:气泡面积映射、alpha/beta/残差标准差和带依据标识图形。
  • 问题 4|怎样确认结果可靠?:检查气泡面积单调、残差均值近零;不得把beta写成总风险或alpha写成稳定跑赢。
  • 问题 5|换一个情境,怎样继续应用?:把CAPM方法应用到另一中性超额收益序列。
  • 作答提示:请依次写清所用数据、分析过程、所得结果、核对方法和拓展思考。课程所需数据见前言中的下载入口;教学平台固定题按页面说明完成。

教师参考解答|答案与说明 1

  • 所用数据与字段:中性对象代码、波动率、平均收益、规模;同一期间与频率,气泡面积按规模单调映射。A/B/C 只是不对应任何企业的纯教学示例。

教师参考解答|代码 1

展开代码(代码区可独立滚动)
import numpy as np  # 导入数值工具以严格核对面积映射
import pandas as pd  # 导入表格工具以构造气泡输入
import matplotlib.pyplot as plt  # 导入绘图工具以生成气泡图
frame=pd.DataFrame({'code':['A','B','C'],'volatility':[.18,.25,.14],'mean_return':[.07,.10,.04],'market_cap':[100,300,80]})  # 构造带业务字段的数据框输入
bubble_sizes=40+260*frame.market_cap/frame.market_cap.max()  # 把规模字段单调映射为气泡面积
ax=frame.plot.scatter('volatility','mean_return',s=bubble_sizes,c='market_cap',colormap='viridis',figsize=(7,3.5),label='教学示例,非市场观测|规模面积')  # 绘制带依据边界的气泡图
for row in frame.itertuples(): ax.annotate(row.code,(row.volatility,row.mean_return))  # 构造带业务字段的数据框输入
ax.set_xlabel('年化波动率'); ax.set_ylabel('年化平均收益率')  # 设置同一时间段坐标轴
ax.set_title('教学示例,非市场观测|规模—风险—收益气泡图')  # 在图内标题持续声明依据边界
ax.legend(title='教学示例,非市场观测')  # 在图例持续声明依据边界
size_order=np.argsort(bubble_sizes.to_numpy())  # 取得按气泡面积排序的位置
cap_order=np.argsort(frame['market_cap'].to_numpy())  # 独立取得按规模排序的位置
strict_mapping=bool(np.array_equal(size_order,cap_order) and np.all(np.diff(bubble_sizes.iloc[cap_order])>0))  # 严格验证面积与规模排序一致且递增
assert strict_mapping is True  # 检查气泡面积单调映射的真值严格为True
plt.tight_layout(); plt.show()  # 显示教师答案气泡图
print('教学示例,非市场观测|气泡映射核对',{'严格单调':strict_mapping,'规模排序':frame.iloc[cap_order]['code'].tolist(),'面积排序':frame.iloc[size_order]['code'].tolist()})  # 输出可见严格核对依据

教师参考解答|答案与说明 2

  • 拓展应用答案|CAPM 超额收益教学示例(非市场观测)

教师参考解答|代码 2

展开代码(代码区可独立滚动)
import numpy as np  # 导入数值工具拟合中性超额收益示例数据
market_excess_fixture=np.array([-.03,-.01,0,.01,.025,.04])  # 构造不对应真实市场的超额收益输入
asset_excess_fixture=np.array([-.041,-.015,.001,.015,.034,.054])  # 构造不对应真实证券的超额收益输入
beta_estimate,alpha_estimate=np.polyfit(market_excess_fixture,asset_excess_fixture,1)  # 拟合时间序列证券特征线
fitted_excess=alpha_estimate+beta_estimate*market_excess_fixture  # 计算模型条件均值
residuals=asset_excess_fixture-fitted_excess  # 提取特质残差以区分总波动与系统性部分
plt.figure(figsize=(6.8,3.2)); plt.scatter(market_excess_fixture,asset_excess_fixture,label='教学示例点'); plt.plot(market_excess_fixture,fitted_excess,label='证券特征线')  # 绘制可见标注的中性示例数据与拟合线
plt.title('教学示例,非市场观测|CAPM超额收益口径'); plt.xlabel('市场超额收益示例数据'); plt.ylabel('资产超额收益示例数据'); plt.legend(title='教学示例,非市场观测'); plt.tight_layout(); plt.show()  # 在标题、轴和图例持续声明依据边界
assert np.isclose(residuals.mean(),0,atol=1e-12)  # 核对含截距最小二乘残差均值为零
print('教学示例,非市场观测|CAPM新案例统计',{'alpha':alpha_estimate,'beta':beta_estimate,'residual_std':residuals.std(ddof=1)})  # 输出带依据边界的模型统计

教师参考解答|答案与说明 3

  • 解释答案:散点图只能展示同一时间段变量关系;气泡面积映射第三变量时要控制尺度。回归阴影是重复抽样意义下的回归均值置信带,不表示单个未来观测有95%概率落入其中。
  • 拓展应用答案:上方代码把对象替换为中性超额收益序列,保持 资产超额收益=alpha+beta×市场超额收益+残差,输出时间序列证券特征线与 alpha/beta/residual_std,并用残差均值检查核对;不得把它称为横截面SML或真实市场依据。
  • 参考结果:标题、图例、图注、替代文本与打印输出均标明“教学示例,非市场观测”的三点气泡图和严格面积排序,以及同样标记的CAPM图与参数表。另行核对:比较规模排序与面积排序且严格递增,并复算一行拟合值与残差。
  • 常见错误:面积用半径线性造成夸张;相关写成 CAPM 因果;随机点使用真实公司名。